Satellite models ================= A forecast round publishes far more than the core model carries. The structural model gives output, inflation and the policy rate; the round also has to say something about consumption, unemployment, a savings identity, sector detail. Those come from a **satellite layer**: small single equations, each fitted on its own, run *after* the core model and *conditional on* it. ``rise.satellite`` is that layer — the third family of model object, alongside the DSGE and the VAR. .. code-block:: matlab m = rise.satellite([ "diff_log(consumption) = a1 + a2*diff_log(gdp)" "unemployment = b1 + b2*unemployment{-1} + b3*diff_log(gdp)" "savings === gdp - consumption" ]); .. contents:: :local: :depth: 2 How it connects to the core model ---------------------------------- Through the **data**, not through an object. A satellite system holds equations and parameters and nothing else: it has no handle on a ``dsge_model``, it is not estimated jointly with one, and nothing feeds back from it into the core. The workflow is: .. code-block:: matlab core = perfect_foresight(m_dsge, 'simul_historical_data', plan); % or simulate(...) detail = simulate(m_sat, core, periods); ``gdp`` in the equations above is simply a name the system reads out of the databank you hand it. Where that databank came from is your business — the core model, the published data, or a mixture. That is what makes the layer a satellite: it orbits the core model, and it is the round that puts them together. Write the transform, get the level ----------------------------------- The point of the object is the left-hand side. Modellers write these equations in growth rates; everyone downstream needs levels. ``diff_log(consumption) = ...`` is fitted and simulated in log differences, and ``simulate`` returns **the level of consumption**. You never write the accumulation. The transforms are the same seven shared with simulation plans (see :doc:`Conditioning on transforms`), so ``diff_log`` means the same thing in both places. ``===`` marks an accounting identity. It is never estimated and never gets a residual. Estimation, equation by equation --------------------------------- A name in an equation is a **variable** until it is declared a parameter. Declaring the coefficients is what tells the system which names to fit: .. code-block:: matlab m.Parameters.a1 = 0; m.Parameters.a2 = 0; info = estimate(m, history, 2:n); The system is recursive by construction, so ordinary least squares equation by equation is consistent and there is nothing to gain from estimating them jointly. ``info`` carries the estimates, their standard errors and the R-squared of each equation. Estimating a system whose coefficients were never declared fits nothing, and says so rather than reporting a clean result with no estimates — that is how somebody comes to believe a model was estimated when it was not. Residual recovery, and why it has to be exact ---------------------------------------------- The two operations a forecast round actually runs: .. code-block:: matlab recovered = residuals(m, history, 2:n); % what residuals does the data imply? back = simulate(m, recovered, 2:n); % put them back These must be exact inverses of each other, through the transform inversion. They are, to about ``1e-13``. **If they were not, every add-factor a forecaster applies would be quietly wrong**, and nobody would find out, because the path would still look plausible. That property is the reason to use this object rather than hand-rolling the accumulation per equation. The horizon belongs to the caller ---------------------------------- ``simulate(m, data, (n+1):(n+12))`` runs past the end of the data. A forecast is by definition periods the data do not reach, so the working array is extended to match. Missing residuals are zero — no judgment is the sensible default. What it refuses ---------------- The order of solution is worked out from the equations, never guessed at. A system that cannot be made recursive is reported by name: .. code-block:: none RISE:satellite:notRecursive the simultaneous block involves: alpha, beta Other refusals carry the same prefix: ``notAnEquation``, ``badLeftHandSide``, ``noExpansion``, ``tooManyTransforms``, ``noInverse``, ``noData``. See also --------- * :doc:`Conditioning on transforms` — the shared transform rules * :doc:`Forecasting and simulation` * :doc:`Simulation plans`